﻿using FreeSql.Aop;
using FreeSql.DataAnnotations;
using FreeSql.Internal.Model;
using Microsoft.Extensions.DependencyInjection;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using WenAntdUI.Helps;
using WenAntdUI.Pages.SysAdmin;
using WenAntdUI.Pages;
using WenAntdUI.Services;
using Yitter.IdGenerator;

namespace WenAntdUI.Extensions;

internal static class FreeSqlServiceExtension
{
    internal static IServiceCollection AddFreeSqlServices(this IServiceCollection services)
    {
        FreeSql.Internal.Utils.TypeHandlers.TryAdd(typeof(Color), new ColorTypeHandler());
        FreeSql.Internal.Utils.TypeHandlers.TryAdd(typeof(Image), new ImageTypeHandler());

        services.AddFreeSqlServices(conn =>
        {
            var connString = AppSettings.GetString("DefaultConnection");
            var dbType = AppSettings.Get<FreeSql.DataType>("DbType");

            if (connString is null)
            {
                AppSettings.Set("DefaultConnection", "DataSource=data.db", "数据连接字符串");
                AppSettings.Set("DbType", FreeSql.DataType.Sqlite, "数据库类型");
                new Settings.SettingsForm().ShowDialog();

                connString = AppSettings.GetString("DefaultConnection");
                dbType = AppSettings.Get<FreeSql.DataType>("DbType");
            }
            return (dbType, connString!);
        }, fsql =>
        {
            fsql.Aop.AuditValue += (s, e) =>
            {
                if (e.AuditValueType == AuditValueType.Insert)
                {
                    if (e.Column.CsName == "CreateTime")
                    {
                        e.Value = DateTime.Now;
                    }
                    else if (e.Column.CsName == "CreateUserName")
                    {
                        var identity = App.GetService<IdentityService>();
                        e.Value = identity?.UserName;
                    }
                }
                else if (e.AuditValueType == AuditValueType.Update)
                {
                    if (e.Column.CsName == "UpdateTime")
                    {
                        e.Value = DateTime.Now;
                    }
                    else if (e.Column.CsName == "UpdateUserName")
                    {
                        var identity = App.GetService<IdentityService>();
                        e.Value = identity?.UserName;
                    }
                }

            };

            fsql.Aop.ConfigEntityProperty += (s, e) =>
            {
                if (e.Property.PropertyType == typeof(Color))
                {
                    e.ModifyResult.MapType = typeof(string);
                    e.ModifyResult.StringLength = 20;
                }
                else if (e.Property.PropertyType == typeof(Image))
                {
                    e.ModifyResult.MapType = typeof(string);
                    e.ModifyResult.StringLength = -1;
                }
            };

            //初始化数据库
            fsql.InitcomDatabase();
        });

        return services;
    }

    private class ColorTypeHandler : TypeHandler<Color>
    {
        public override Color Deserialize(object value)
        {
            return ColorTranslator.FromHtml(value?.ToString() ?? "#00");
        }

        public void FluentApi(ColumnFluent col) => col.MapType(typeof(string)).StringLength(20);
        public override object Serialize(Color value)
        {
            return ColorTranslator.ToHtml((Color)value);
        }
    }
    private class ImageTypeHandler : TypeHandler<Image>
    {
        public override Image Deserialize(object value)
        {
            try
            {
                return ImageHelp.GetImage((string)value);
            }
            catch (Exception)
            {
                return null;
            }
        }
        public void FluentApi(ColumnFluent col) => col.MapType(typeof(string)).StringLength(-1);

        public override object Serialize(Image value)
        {
            try
            {
                return ImageHelp.ToBase64String(value);
            }
            catch (Exception)
            {
                return null;
            }
        }
    }

    internal static void InitcomDatabase(this IFreeSql fsql)
    {
        fsql.CodeFirst.SyncStructure<SysMenu>();
        fsql.CodeFirst.SyncStructure<SysRole>();
        fsql.CodeFirst.SyncStructure<SysRoleMenu>();
        fsql.CodeFirst.SyncStructure<SysUser>();
        fsql.CodeFirst.SyncStructure<SysUserRole>();

        if (!fsql.Select<SysMenu>().Any())
        {
            var menus = new List<SysMenu>
            {
                new() { Code = "sysadmin",ParentCode="", Name = "系统管理",MenuType=MenuType.Menu, Icon = "FontColorsOutlined" },
                new() { Code = "adminuser",ParentCode="sysadmin", Name = "用户管理",MenuType=MenuType.Menu, Icon = "UserOutlined" ,ControlType=typeof(SysUserPage).FullName},
                new() { Code = "setRole",ParentCode="adminuser", Name = "设置角色",MenuType=MenuType.Block},
                new() { Code = "rePassword",ParentCode="adminuser", Name = "重置密码",MenuType=MenuType.Block},
                new() { Code = "adminuser:delete",ParentCode="adminuser", Name = "表格删除按钮",MenuType=MenuType.Block},
                new() { Code = "adminuser:add",ParentCode="adminuser", Name = "表格新增按钮",MenuType=MenuType.Block},
                new() { Code = "adminuser:edit",ParentCode="adminuser", Name = "表格编辑按钮",MenuType=MenuType.Block},
                new() { Code = "admindict",ParentCode="sysadmin", Name = "字典管理",MenuType=MenuType.Menu, Icon = "PicLeftOutlined" ,ControlType=typeof(SysDictPage).FullName},
                new() { Code = "adminrole",ParentCode="sysadmin", Name = "角色管理",MenuType=MenuType.Menu, Icon = "UsergroupDeleteOutlined" ,ControlType=typeof(SysRolePage).FullName},
                new() { Code = "adminmeun",ParentCode="sysadmin", Name = "菜单管理",MenuType=MenuType.Menu, Icon = "MenuOutlined" ,ControlType=typeof(SysMenuPage).FullName},
                new() { Code = "iconshow",ParentCode="", Name = "图标预览",MenuType=MenuType.Menu, Icon = "PictureOutlined" ,ControlType=typeof(IconPage).FullName},
                new() { Code = "userinfoconfig",ParentCode="", Name = "用户信息设置",MenuType=MenuType.Menu, Icon = "UsergroupAddOutlined" ,ControlType=typeof(UserInfoPage).FullName},
            };
            fsql.Insert<SysMenu>().AppendData(menus).ExecuteEffects();
        }

        if (!fsql.Select<SysRole>().Any())
        {
            var roles = new List<SysRole>()
            {
                new (){RoleName="admin",Description="管理员"},
                new (){RoleName="user",Description="用户"},
            };
            fsql.Insert<SysRole>().AppendData(roles).ExecuteEffects();
        }

        if (!fsql.Select<SysRoleMenu>().Any())
        {
            var rolemenus = fsql.Select<SysMenu>().ToList(a => a.Code).Select(a => new SysRoleMenu() { MenuCode = a, RoleName = "admin" });
            fsql.Insert<SysRoleMenu>().AppendData(rolemenus).ExecuteEffects();
        }

        if (!fsql.Select<SysUser>().Any())
        {
            var users = new List<SysUser>()
            {
                new (){UserName="admin",DisplayName="管理员",Password="TXI6UvYXHqzmn/BLj4/lzRYDobJs+PK9uJnT2QStCRA=",PasswordSalt="I9UYqVsgQXZbCTf5zowHGXYKxzRVeoDLAKbJRu7Q0VLRnolR"}
            };
            fsql.Insert<SysUser>().AppendData(users).ExecuteEffects();
        }

        if (!fsql.Select<SysUserRole>().Any())
        {
            var userroles = new List<SysUserRole>()
            {
                new (){UserName="admin",RoleName="admin"}
            };
            fsql.Insert<SysUserRole>().AppendData(userroles).ExecuteEffects();
        }
    }
}
